#include<stdio.h>
#include<malloc.h>
#include<pthread.h>

pthread_mutex_t comm = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t product_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t constumer_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

typedef int data_type;
typedef struct list{
	data_type _data;
	struct list *_next;
}list;
void init_list(list *head)
{
	head->_next=NULL;
}
void push(list *head,data_type data)
{
	if(head->_next==NULL)
	{
		list *tmp=(list*)malloc(sizeof(list));
		tmp->_data=data;
		tmp->_next=NULL;
		head->_next=tmp;
	}
	else{
		list *tmp=(list*)malloc(sizeof(list));
		tmp->_next=head->_next;
		tmp->_data=data;
		head->_next=tmp;
	}
}

int pop(list *head,data_type*data)
{
	if(head->_next==NULL)
	{
		return -1;
	}
	else
	{
		*data=head->_next->_data;
		list *tmp=head->_next;
		head->_next=tmp->_next;
		free(tmp);
		return 0;
	}
}

void display_list(list *head)
{
	list *tmp=head->_next;
	while(tmp!=NULL)
	{
		printf("%d",tmp->_data);
		fflush(stdout);
		tmp=tmp->_next;
	}
}
list head;

void * producter1(void *arg)
{
	int i=0;
	while(1)
	{
		pthread_mutex_lock(&comm);
	    push(&head,i);
		pthread_mutex_unlock(&comm);
	    printf("producter1 :%d\n",i++);
		pthread_cond_broadcast(&cond);
		sleep(1);
	}
}
//void * producter2(void *arg)
//{
//	int i=10;
//	while(1)
//	{
//		pthread_mutex_lock(&comm);
//	    push(&head,i);
//		pthread_mutex_unlock(&comm);
//	    printf("producter2 :%d\n",i++);
//		pthread_cond_signal(&cond);
//		sleep(1);
//	}
//}
void * constumer1(void *arg)
{
	data_type data;
	sleep(10);
	while(1)
	{
			sleep(1);
		pthread_mutex_lock(&comm);
		while(pop(&head,&data)<0)
		{
			pthread_cond_wait(&cond,&comm);
			printf("buff is empty\n");
		}
		printf("constumer1 :%d\n",data);
		pthread_mutex_unlock(&comm);
	}
}
void * constumer2(void *arg)
{
	data_type data;
	sleep(10);
	while(1)
	{
			sleep(1);
		pthread_mutex_lock(&comm);
		while(pop(&head,&data)<0)
		{
			pthread_cond_wait(&cond,&comm);
			printf("buff is empty\n");
		}
		printf("constumer2 :%d\n",data);
		pthread_mutex_unlock(&comm);
	}
}






int main()
{
	init_list(&head);
	pthread_t _producter1,_producter2,_constumer1,_constumer2;
	pthread_create(&_producter1,NULL,producter1,NULL);
//	pthread_create(&_producter2,NULL,producter2,NULL);
	pthread_create(&_constumer1,NULL,constumer1,NULL);
	pthread_create(&_constumer2,NULL,constumer2,NULL);
	pthread_join(_producter1,NULL);
//	pthread_join(_producter2,NULL);
	pthread_join(_constumer1,NULL);
	pthread_join(_constumer2,NULL);

//	int i=0;
//	data_type data;
//	while(i<10)
//	{
//		push(&head,i++);
//		display_list(&head);
//		printf("\n");
//	}
//	while(i-->0)
//	{
//		pop(&head,&data);
//		display_list(&head);
//		printf("\n");
//	}
	return 0;
}
















